﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Text.RegularExpressions;


namespace EntitiesLayer
{
    //no es thread safe.
    public class Usuario : IEntity
    {
     
       

        //private static  Regex FormatoClave = new Regex(@"((?=.*[A-Z]+)(?=.*[a-z]+)(?=.*[^\d\w ]+)(?=.*\d+))");
        
        private int idUsuario;
        public int Id
        {
            get { return idUsuario; }

        }

        public bool ClaveEsAuto { get; set; }
        
        private string identificacion;

        public string Identificacion
        {
            get { return identificacion; }
            set { identificacion = value; }
        }
        private string nombre;

        public string Nombre
        {
            get { return nombre; }
            set { nombre = value; }
        }
        private string pApellido;

        public string PApellido
        {
            get { return pApellido; }
            set { pApellido = value; }
        }
        private string sApellido;

        public string SApellido
        {
            get { return sApellido; }
            set { sApellido = value; }
        }
        private DateTime fechaNacimiento;

        public DateTime FechaNacimiento
        {
            get { return fechaNacimiento; }
            set { fechaNacimiento = value; }
        }
        private DateTime fechaIngreso;

        public DateTime FechaIngreso
        {
            get { return fechaIngreso; }
            set { fechaIngreso = value; }
        }
        private Genero genero;

        public char GeneroCode {
            get { return (char)genero; }
        }
        public Genero Genero
        {
            get { return genero; }
            set { genero = value; }
        }
        private Bitmap foto;

        public Bitmap Foto
        {
            get { return foto; }
            set { foto = value; }
        }
        public string FotoBase64 {

            get { return foto!=null?Convert.ToBase64String(foto.ToByte()):""; }
        }

        private string alias;

        public string Alias
        {
            get { return alias; }
            set { alias = value; }
        }
        private string nombreUsuario;

        public string NombreUsuario
        {
            get { return nombreUsuario; }
            set { nombreUsuario = value; }
        }
        private string discripcionTipoId;

        public string DiscripcionTipoId
        {
            get { return discripcionTipoId; }
            set { discripcionTipoId = value; }
        }
        private string nacionalidad;

        public string Nacionalidad
        {
            get { return nacionalidad; }
            set { nacionalidad = value; }
        }

        //no se levanta por demanda es incesario. Podria haver un atributo idRol para el modificar.
        private Rol rol;
        public Rol Rol {

            set { rol = value; }
            get { return rol; }
        }

        private TipoUsuario tipo;

        public TipoUsuario Tipo { 
            set { tipo = value; } 
        }
        public char TipoCode {
            get { return (char)tipo; }
        }

        private EstadoUsuario estado;
        public char EstadoCode {
            get { return (char)estado; }
        }
        public EstadoUsuario Estado 
        {
            set { estado = value; }
            get { return estado; }
        
        }



        private Lazy<IList<CorreoElectronico>> listaCorreo;
        public IList<CorreoElectronico> ListaCorreo 
        {
            get { return listaCorreo.NullSaveValue(); }
        }

        private Lazy<IList<Telefono>> listaTelefonos;
        public IList<Telefono> ListaTelefono {
            get { return listaTelefonos.NullSaveValue(); }
        }

        private Lazy<IList<Referencia>> listaReferencias;
        public IList<Referencia> ListaReferencia {
            get { return listaReferencias.NullSaveValue(); }
        }

        /// <summary>
        /// En caso de ser un funcionario este lazy retorna las citas en las cuales el es el encargado.
        /// En caso de ser un cliente este lazy obviamente retorna las citas en las cuales el usuario es el cliente. 
        /// </summary>
        private readonly Lazy<IList<Cita>> listaCitasPorAtender;
        public IList<Cita> ListaCitasPorAtender
        {
            get { return listaCitasPorAtender.NullSaveValue(); }
        }

        private readonly Lazy<IList<Notificacion>> listaNotificacion;
        public IList<Notificacion> ListaNotificacion
        {
            get { return listaNotificacion.NullSaveValue(); }
        }

        public Usuario(
            string identificacion, string nombre, string PApellido,
            string SApellido, DateTime fechaNacimiento, DateTime fechaIngreso, 
            Genero genero, Bitmap foto, string alias, string nombreUsuario,
            string discripcionTipoId, string nacionalidad, Rol rol, 
            //opcionales
            EstadoUsuario estado = EstadoUsuario.activo, 
            Lazy<IList<CorreoElectronico>> listaCorreos = null,
            Lazy<IList<Telefono>> listaTelefonos = null,
            Lazy<IList<Referencia>> listaReferencias = null,
            Lazy<IList<Cita>> listaCitasPorAtender=null,
            Lazy<IList<Notificacion>> listaNotificacion=null,
            bool ClaveEsAuto = true, int idUsuario = 0)
        {
            this.idUsuario = idUsuario;
            Identificacion=identificacion;
            Nombre = nombre;
            this.PApellido = PApellido;
            this.SApellido = SApellido;
            FechaNacimiento = fechaNacimiento;
            FechaIngreso = fechaIngreso;
            Genero = genero;
            Foto = foto;
            Alias = alias;
            NombreUsuario = nombreUsuario;
            DiscripcionTipoId = discripcionTipoId;
            Nacionalidad = nacionalidad;
            Rol = rol;
            Estado = estado;
            this.listaCorreo = listaCorreos;
            this.listaTelefonos = listaTelefonos;
            this.listaReferencias = listaReferencias;
            this.ClaveEsAuto = ClaveEsAuto;
            this.listaCitasPorAtender = listaCitasPorAtender;
            this.listaNotificacion = listaNotificacion;
           
        }


        public Usuario()
        {

        }


       
       public override string ToString()
        {

            return"\n"+(this is Cliente?"Cliente":"Funcionario")
                +"\nIdentificacion: " + Identificacion
                +"\nNombre: " + Nombre + " " + PApellido + " " + SApellido
                +"\nNombre Usuario: "+NombreUsuario
                +"\nNacionalidad: "+Nacionalidad
                +"\nRol: " +Rol.Nombre;
                
                
        }

       public string GenerarClaveDefualt() {
           
           if(ClaveEsAuto)
                return  nombre[0].ToString().ToUpper() 
                    +PApellido + SApellido[0].ToString().ToUpper()
                    + "-123";

           return null;
       }

       
    }

    public enum EstadoUsuario{
        activo='A',
        inactivo='I'
    }

    public enum TipoUsuario { 
    
        funcionario='F',
        cliente='C'
    }
}
